<template>
    <!-- 对话框表单 -->
    <el-dialog
        class="ba-operate-dialog"
        :close-on-click-modal="false"
        :model-value="['park','charging','shop'].includes(baTable.form.operate!)"
        @close="onMyClose"
        width="70%"
    >
        <template #header>
            <div class="title" v-drag="['.ba-operate-dialog', '.el-dialog__header']" v-zoom="'.ba-operate-dialog'">
                字段配置
            </div>
        </template>
        <div class="default-main"   v-loading="baTable.form.loading">
            <div style="padding: 10px;" v-if="baTable.form.extend!.table_name">
                <el-row v-loading="state.loading.init" class="fields-box" :gutter="20">
                    <el-col :xs="24" :span="6">
                        <div class="field-box"  :ref="tabsRefs.set">
                            <div v-for="(field, index) in fieldItem.common" :key="index" class="field-item">
                                <span>{{ field.title }}</span>
                            </div>
                        </div>
                    </el-col>
                    <el-col :xs="24" :span="10">
                        <div ref="designWindowRef" class="design-window ba-scroll-style">
                            <div
                                v-for="(field, index) in state.fields"
                                :key="index"
                                :class="index === state.activateField ? 'activate' : ''"
                                @click="onActivateField(index)"
                                class="design-field-box"
                                :data-id="index"
                            >
                                <div class="design-field">
                                    <span>字段名：</span>
                                    <BaInput
                                        @pointerdown.stop
                                        class="design-field-name-input"
                                        :model-value="field.title"
                                        type="string"
                                        :attr="{
                                            size: 'small',
                                            onInput: ($event: string) => onFieldNameChange($event, index),
                                        }"
                                    />
                                </div>
                            </div>
                            <div class="design-field-empty" v-if="!state.fields.length && !state.draggingField">
                                退拽字段到此区域
                            </div>
                        </div>
                    </el-col>
                    <el-col :xs="24" :span="8">
                        <div class="field-config ba-scroll-style">
                            <div v-if="state.activateField === -1" class="design-field-empty">
                                字段配置
                            </div>
                            <div v-else :key="'activate-field-' + state.activateField">
                                <el-form label-position="top">
                                    <el-divider content-position="left" v-if="state.fields[state.activateField].data.source == 'endtime'">

                                        {{ state.fields[state.activateField].notes }}
                                    </el-divider>
                                    <el-form-item label="数据来源" v-if="state.fields[state.activateField].data.source == 'store'">
                                        <el-select
                                            @change="onFieldDesignTypeChange"
                                            class="w100"
                                            :model-value="state.fields[state.activateField].data!.source_field"
                                            placement="bottom"
                                        >
                                            <el-option v-for="(item, idx) in baTable.form.extend?.store_list" 
                                            :key="idx" :label="item.label" 
                                            :value="item.value" />
                                        </el-select>
                                    </el-form-item>

                                    <el-form-item label="单选选项" v-if="state.fields[state.activateField].data.source == 'select'">
                                        <el-input-tag @change="onSelectOptionsChange" 
                                        v-model="state.fields[state.activateField].data!.replaceValue.label" clearable 
                                        placeholder="请输入选项" />
                                    </el-form-item>
                                    <el-form-item v-if="state.fields[state.activateField].data.source == 'select' ">
                                        <div>选择占比%</div>
                                        <div class="slider-demo-block" v-for="(item, idx) in state.fields[state.activateField].data!.replaceValue.odds" :key="idx">
                                            <span class="demonstration">{{ state.fields[state.activateField].data!.replaceValue.label[idx] }} </span>
                                            <el-slider v-model="state.fields[state.activateField].data!.replaceValue.odds[idx]" />
                                        </div>
                                    </el-form-item>

                                    <el-form-item label="包含字符串" v-if="state.fields[state.activateField].data.source == 'random'">

                                        <el-select class="w100" v-model="state.fields[state.activateField].data!.randomdata.value" multiple placeholder="请选择包含字符串">

                                            <el-option
                                                v-for="item in state.fields[state.activateField].data!.randomdata.options"
                                                :key="item.value"
                                                :label="item.label"
                                                :value="item.value"
                                            />
                                        </el-select>
                                    </el-form-item>
                                    

                                    <el-form-item label="生成时间范围" v-if="['starttime','endtime'].includes(state.fields[state.activateField].data.source)">
                                        <el-date-picker
                                            v-model="state.fields[state.activateField].data.timeRange"
                                            type="datetimerange"
                                            range-separator="到"
                                            value-format="YYYY-MM-DD HH:mm:ss"
                                            start-placeholder="起始时间"
                                            end-placeholder="结束时间"
                                            />
                                    </el-form-item>
                                    <!-- <el-form-item label="开始时间后N小时" v-if="['endtime'].includes(state.fields[state.activateField].data.source)">
                                        <el-input-number
                                            v-model="state.fields[state.activateField].data.interval"
                                            :min="0"
                                            :step="1"
                                            controls-position="right"
                                        />
                                    </el-form-item> -->
                                    <el-form-item label="金额范围" v-if="state.fields[state.activateField].data.source == 'money' ">
                                        <el-col :span="11">
                                            <el-input-number v-model="state.fields[state.activateField].data.min" :min="0" :max="1000000" />
                                        </el-col>
                                        <el-col :span="2" class="text-center">
                                            <span class="text-gray-500">-</span>
                                        </el-col>
                                        <el-col :span="11">
                                            <el-input-number v-model="state.fields[state.activateField].data.max" :min="0" :max="1000000" @change="handleChange" />
                                        </el-col>
                                    </el-form-item>
                                    
                                    <FormItem
                                        v-if="!isEmpty(state.fields[state.activateField].table.operator)"
                                        label="公共搜索操作符"
                                        type="select"
                                        v-model="state.fields[state.activateField].table.operator.value"
                                    
                                        :input-attr="{
                                            clearable:false,
                                            content: state.fields[state.activateField].table.operator.options ?? {},
                                        }"
                                    />

                                    <FormItem
                                        v-if="!isEmpty(state.fields[state.activateField].table.timeFormat)"
                                        label="时间格式"
                                        type="select"
                                        v-model="state.fields[state.activateField].table.timeFormat.value"
                                    
                                        :input-attr="{
                                            clearable:false,
                                            content: state.fields[state.activateField].table.timeFormat.options ?? {},
                                        }"
                                    />
                                </el-form>
                            </div>
                        </div>
                    </el-col>
                </el-row>
            </div>
            
        </div>

        <template #footer>
            <div :style="'width: calc(100% - ' + baTable.form.labelWidth! / 1.8 + 'px)'">
                <el-button @click="onMyClose">取消</el-button>
                <el-button v-blur :loading="baTable.form.submitLoading" @click="onMySubmit" type="primary">
                    保存
                </el-button>
            </div>
        </template>
    </el-dialog>
</template>

<script setup lang="ts">
import BaInput from '/@/components/baInput/index.vue'
import FormItem from '/@/components/formItem/index.vue'
import { reactive, ref, inject, watch,onMounted,nextTick } from 'vue'
import type baTableClass from '/@/utils/baTable'
import { ElMessage, ElMessageBox, type MessageHandler } from 'element-plus'
import type { TableDesignChange } from '/@/views/backend/crud/index'
import { useTemplateRefsList } from '@vueuse/core'
import Sortable from 'sortablejs'
import type { SortableEvent } from 'sortablejs'
import { cloneDeep, range, isEmpty } from 'lodash-es'
import createAxios from '../utils/axios'


const designWindowRef = ref()
const tabsRefs = useTemplateRefsList<HTMLElement>()

const baTable = inject('baTable') as baTableClass

const save = (params:anyObj) => {
    createAxios({
        url:'/admin/fields/save',
        method:'post',
        data:params
    }).then((res) => {
        ElMessage.success('保存成功')
        baTable.form.submitLoading = false
        baTable.table.column = [];
        baTable.onTableHeaderAction('refresh', {})

        onMyClose()
    }).finally(() => {
        baTable.form.submitLoading = false
    })

}
const onMySubmit = () =>{
    let isPass = true
    state.fields.forEach((item,i) => {
        if(item.data.source == 'select') {
            if(item.data.replaceValue?.label.length == 0){
                ElMessage.error(item.title+'请输入选项')
                isPass = false
                return false
            }
        }else if(item.data.source == 'store'){
            if(item.data.source_field == ''){
                ElMessage.error(item.title+'请选择数据来源')
                isPass = false
                return false
            }
        }else if(item.data.source == 'starttime'){
            if(item.data.timeRange?.length == 0){
                ElMessage.error(item.title+'请选择时间范围')
                isPass = false
                return false
            }
        }else if(item.data.source == 'endtime'){
            if(item.data.timeRange?.length == 0){
                ElMessage.error(item.title+'请选择时间范围')
                isPass = false
                return false
            }
            // 判断是否选择了开始时间 也就是state.fields 中是否有starttime
            let isStartTime = state.fields.filter(item => item.data.source == 'starttime').length > 0

            if(!isStartTime){
                ElMessage.error(item.title+'请先选择开始时间')
                isPass = false
                return false
            }
        }else if(item.data.source == 'random'){
            if(item.data.randomdata?.value.length == 0){
                ElMessage.error(item.title+'请选择包含字符串')
                isPass = false
                return false

            }
        }
        item.name = 'field'+i
        item.field_sort = i
        item.table.prop = 'datas.field'+i
    })
    if(!isPass) return false
    state.activateField = -1
    const params = {
        filed_item:state.fields,
        name:baTable.form.operate,
        is_del:0
    }
    ElMessageBox.confirm(
        '',
        '是否清除数据',
        {
            confirmButtonText: '是',
            cancelButtonText: '否',
            type: 'warning',
        }
    ).then(() => {
        params.is_del = 1
        baTable.form.submitLoading = true
        save(params)
    })
    .catch(() => {
        params.is_del = 0
        baTable.form.submitLoading = true
        save(params)
    })
    
}
const onMyClose = () => {
    state.fields = []
    state.activateField = -1
    baTable.form.extend = {}
    baTable.toggleForm()
}

const state: {
    loading: {
        init: boolean
        generate: boolean
        remoteSelect: boolean
    }
    table: {
        name: string
        comment: string
        quickSearchField: string[]
        defaultSortField: string
        formFields: string[]
        columnFields: string[]
        defaultSortType: string
        generateRelativePath: string
        isCommonModel: number
        modelFile: string
        controllerFile: string
        validateFile: string
        webViewsDir: string
        databaseConnection: string
        designChange: TableDesignChange[]
        rebuild: string
    }
    fields: FieldItem[]
    activateField: number
    fieldCollapseName: string[]
    remoteSelectPre: {
        show: boolean
        index: number
        fieldList: anyObj
        modelFileList: anyObj
        controllerFileList: anyObj
        loading: boolean
        hideDelField: boolean
        form: {
            table: string
            pk: string
            label: string
            joinField: string[]
            sourceConfigType: 'crud' | 'custom'
            remoteUrl: string
            modelFile: string
            controllerFile: string
            primaryTableAlias: string
        }
    }
    showHeaderSeniorConfig: boolean
    confirmGenerate: {
        show: boolean
        menu: boolean
        table: boolean
        controller: boolean
    }
    draggingField: boolean
    showDesignChangeLog: boolean
    error: {
        tableName: string
        fieldName: MessageHandler | null
        fieldNameDuplication: MessageHandler | null
    }
} = reactive({
    loading: {
        init: false,
        generate: false,
        remoteSelect: false,
    },
    table: {
        name: '',
        comment: '',
        quickSearchField: [],
        defaultSortField: '',
        formFields: [],
        columnFields: [],
        defaultSortType: 'desc',
        generateRelativePath: '',
        isCommonModel: 0,
        modelFile: '',
        controllerFile: '',
        validateFile: '',
        webViewsDir: '',
        databaseConnection: '',
        designChange: [],
        rebuild: 'No',
    },
    fields: [],
    activateField: -1,
    fieldCollapseName: ['common', 'base', 'senior'],
    remoteSelectPre: {
        show: false,
        index: -1,
        fieldList: [],
        modelFileList: [],
        controllerFileList: [],
        loading: false,
        hideDelField: false,
        form: {
            table: '',
            pk: '',
            label: '',
            joinField: [],
            sourceConfigType: 'crud',
            remoteUrl: '',
            modelFile: '',
            controllerFile: '',
            primaryTableAlias: '',
        },
    },
    showHeaderSeniorConfig: false,
    confirmGenerate: {
        show: false,
        menu: false,
        table: false,
        controller: false,
    },
    draggingField: false,
    showDesignChangeLog: false,
    error: {
        tableName: '',
        fieldName: null,
        fieldNameDuplication: null,
    },
})
interface fieldItemData {
    source:'mobile'|'money'|'car'|'ip'|'select'|'store'|'starttime'|'endtime'|'random',

    prefix?:string
    source_field?:string
    timeRange?:[]
    replaceValue?:{
        label:string[],
        odds:number[]
    }
    randomdata?:{
        options:anyObj,
        value:string[]
    }

    interval?:number
}

interface FieldItem {
    name:string,
    title:string,
    designType:string,
    field_sort:number,
    data:fieldItemData,
    table:{
        prop:string,
        operator?:anyObj,
        timeFormat?:anyObj
        sortable:boolean
    }
    notes?:string
}

const timeFormatOptions = {
    'yyyy-mm-dd hh:MM:ss':'年-月-日 时:分:秒',
    'yyyy-mm-dd hh:MM':'年-月-日 时:分',
    'yyyy-mm-dd hh':'年-月-日 时',
    'yyyy-mm-dd':'年-月-日',
    'yyyy-mm':'年-月',
    'yyyy':'年',
}


const fieldItem: {
    common: FieldItem[]
} = {
    common:[
        {
            name:"",
            title:"数据仓库名称",
            designType:"string",
            field_sort:1,
            data:{
                source:"store",
                source_field:""
            },
            table:{
                operator:{
                    options:{false:'禁用搜索',eq:'等于',LIKE:'模糊查询'},
                    type: "select",
                    value: "LIKE"
                },
                prop:"",
                sortable:false
            }
        },
        {
            name:"",
            title:"手机号",
            designType:"string",
            field_sort:0,
            data:{
                source:"mobile"
            },
            table:{
                operator:{
                    options:{false:'禁用搜索',eq:'等于',LIKE:'模糊查询'},
                    type: "select",
                    value: "LIKE"
                },
                prop:"",
                sortable:false
            }
        },
        {
            name:"",
            title:"金额",
            designType:"string",
            field_sort:1,
            data:{
                source:"money",
                min:1,
                max:100
            },
            table:{
                operator:{
                    options:{false:'禁用搜索',eq:'等于',LIKE:'模糊查询'},
                    type: "select",
                    value: "LIKE"
                },
                prop:"",
                sortable:false
            }
        },
        {
            name:"",
            title:"车牌号",
            designType:"string",
            field_sort:0,
            data:{
                source:"car",
                prefix:""
            },
            table:{
                operator:{
                    options:{false:'禁用搜索',eq:'等于',LIKE:'模糊查询'},
                    type: "select",
                    value: "LIKE"
                },
                prop:"",
                sortable:false
            }
        },
        {
            name:"",
            title:"IP",
            designType:"string",
            field_sort:4,
            data:{
                source:"ip"
            },
            table:{
                operator:{
                    options:{false:'禁用搜索',eq:'等于',LIKE:'模糊查询'},
                    type: "select",
                    value: "LIKE"
                },
                prop:"",
                sortable:false
            }
        },
        {
            name:"",
            title:"开始时间",
            designType:"datetime",
            field_sort:0,
            data:{
                source:"starttime",
                timeRange:[]
            },
            table:{
                operator:{
                    options:{false:'禁用搜索',RANGE:'时间范围'},
                    type: "select",
                    value: "RANGE"
                },
                prop:"",
                timeFormat:{
                    options:timeFormatOptions,
                    type: "select",
                    value: "yyyy-mm-dd hh:MM:ss"
                },
                sortable:false
            }
        },
        {
            name:"",
            title:"结束时间",
            designType:"datetime",
            field_sort:0,
            data:{
                source:"endtime",
                timeRange:[],
                interval:0
            },
            notes:'必须生成开始时间！',
            table:{
                operator:{
                    options:{false:'禁用搜索',RANGE:'时间范围'},
                    type: "select",
                    value: "RANGE"
                },
                timeFormat:{
                    options:timeFormatOptions,
                    type: "select",
                    value: "yyyy-mm-dd hh:MM:ss"
                },
                prop:"",
                sortable:false
            }
        },
        {
            name:"",
            title:"单选",
            designType:"select",
            field_sort:0,
            data:{
                source:"select",
                replaceValue:{
                    label:[],
                    odds:[]
                }
            },
            table:{
                operator:{
                    options:{false:'禁用搜索',eq:'等于'},
                    type: "select",
                    value: "eq"
                },
                prop:"",
                sortable:false
            }
        },
        {
            name:"",
            title:"随机字符串",
            designType:"string",
            field_sort:0,
            data:{
                source:"random",
                randomdata:{
                    options:[
                        // {
                        //     label:'汉字',
                        //     value:'chs'
                        // },
                        {
                            label:'姓名',
                            value:'username'
                        },
                        {
                            label:'昵称',
                            value:'nickname'
                        },
                        {
                            label:'数字',
                            value:'number'
                        },
                        {
                            label:'字母',
                            value:'alpha'
                        }   
                    ],
                    value:[]
                }
            },
            table:{
                operator:{
                    options:{false:'禁用搜索',eq:'等于',LIKE:'模糊查询'},
                    value: "LIKE"
                },
                prop:"",
                sortable:false
            }
        }
    ]
}

const onActivateField = (idx: number) => {
    state.activateField = idx
}

const onSelectOptionsChange = (val: string[], index: number) => {
    state.fields[state.activateField].data!.replaceValue!.label = val
    state.fields[state.activateField].data!.replaceValue!.odds = val.map(() => 100)
}


/**
 * 字段名修改
 */
const onFieldNameChange = (val: string, index: number) => {
    state.fields[index].title = val
}


/**
 * 删除字段
 * @param index 
 */
const onDelField = (index: number) => {
    if (!state.fields[index]) return
    state.activateField = -1
    state.fields.splice(index, 1)
}


interface SortableEvt extends SortableEvent {
    originalEvent?: DragEvent
}

const onFieldDesignTypeChange = (v:string) => {
    state.fields[state.activateField].data!.source_field = v
}



watch(() => baTable.form.extend, async (newVal, oldVal) => {
    if(!isEmpty(newVal)){
        await nextTick()
        state.fields = newVal.field_item;
        if(designWindowRef.value){
            const sortable = Sortable.create(designWindowRef.value, {
            group: 'design-field',
            animation: 200,
            filter: '.design-field-empty',
            onAdd: (evt: SortableEvt) => {
                const name = evt.originalEvent?.dataTransfer?.getData('name')
                const field = fieldItem[name as keyof typeof fieldItem]
                if (field && field[evt.oldIndex!]) {
                    const data = cloneDeep(field[evt.oldIndex!])
                    const l = state.fields.length
                    data.name = 'field' + l
                    data.field_sort = l;
                    data.table.prop = 'datas.'+data.name
                    // 插入字段
                    state.activateField = evt.newIndex!
                    state.fields.splice(evt.newIndex!, 0, data)
                }
                evt.item.remove()
                nextTick(() => {
                    sortable.sort(range(state.fields.length).map((value) => value.toString()))
                })
            },
            onEnd: (evt) => {
                const temp = state.fields[evt.oldIndex!]
                state.fields.splice(evt.oldIndex!, 1)
                state.fields.splice(evt.newIndex!, 0, temp)

                // logTableDesignChange({
                //     type: 'change-field-order',
                //     index: evt.newIndex!,
                //     newName: '',
                //     oldName: temp.name,
                //     after: evt.newIndex === 0 ? 'FIRST FIELD' : state.fields[evt.newIndex! - 1].name,
                // })

                nextTick(() => {
                    sortable.sort(range(state.fields.length).map((value) => value.toString()))
                })
            },
        })
        }
        
        tabsRefs.value.forEach((item, index) => {
            Sortable.create(item, {
                sort: false,
                group: {
                    name: 'design-field',
                    pull: 'clone',
                    put: false,
                },
                animation: 200,
                setData: (dataTransfer) => {
                    dataTransfer.setData('name', Object.keys(fieldItem)[index])
                },
                onStart: () => {
                    state.draggingField = true
                },
                onEnd: () => {
                    state.draggingField = false
                },
            })
        })
    }
})
// onMounted(() => {
   
   
// })

</script>

<style scoped lang="scss">

// ::v-deep .el-dialog__body {
//     background-color: #e5e5e5 !important; /* 替换 #your-color 为你想要的背景颜色 */
// }

// :deep(.ba-operate-dialog .el-dialog__body) {
//     background-color: #e5e5e5 !important;

// }
// /deep/ .el-dialog__body {
//   background-color: #f0f0f0; /* 修改背景颜色 */
// }

.default-main {
    margin-bottom: 0;
    background: #e5e5e5;
    // padding: 10px;
}

.field-box {
    padding: 10px;
    height: calc(58vh - 20px);
    background-color: #fff;
}
.field-config {
    overflow-x: auto;
    height: calc(58vh - 20px);
    padding: 20px;
    background-color: var(--ba-bg-color-overlay);
}
.field-item {
    display: inline-block;
    padding: 3px 16px;
    border: 1px dashed var(--el-border-color);
    border-radius: var(--el-border-radius-base);
    margin: 6px;
    cursor: pointer;
    user-select: none;
    &:hover {
        border-color: var(--el-color-primary);
    }
}
.design-field-empty {
    display: flex;
    height: 100%;
    color: var(--el-color-info);
    font-size: var(--el-font-size-medium);
    align-items: center;
    justify-content: center;
}
.design-window {
    overflow-x: auto;
    height: calc(58vh - 20px);

    border-radius: var(--el-border-radius-base);
    background-color: var(--ba-bg-color-overlay);
    border: v-bind('state.draggingField ? "1px dashed var(--el-color-primary)":(state.fields.length ? "none":"1px dashed var(--el-border-color)")');
    .design-field-box {
        display: flex;
        padding: 10px;
        align-items: center;
        border: 1px dashed var(--el-border-color);
        border-radius: var(--el-border-radius-base);
        margin-bottom: 2px;
        cursor: pointer;
        user-select: none;
        .design-field {
            padding-right: 10px;
        }
        .design-field-name-input {
            width: 200px;
        }
        .design-field-name-comment {
            width: 100px;
        }
        .design-field-right {
            margin-left: auto;
        }
        &:hover {
            border-color: var(--el-color-primary);
        }
    }
    .design-field-box.activate {
        border-color: var(--el-color-primary);
    }
}
.fields-box {
    // margin-top: 36px;
}
.slider-demo-block {
  width: 100%;
  display: flex;
  align-items: center;
}
.slider-demo-block .el-slider {
  margin-top: 0;
  margin-left: 12px;
}
.slider-demo-block .demonstration {
  font-size: 14px;
  color: var(--el-text-color-secondary);
  line-height: 44px;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  margin-bottom: 0;
}
.slider-demo-block .demonstration + .el-slider {
  flex: 0 0 70%;
}
</style>